package br.com.wssa.email.util;

import java.io.ByteArrayOutputStream;
import java.util.Date;
import java.util.List;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.commons.collections.CollectionUtils;

import br.com.wssa.email.dto.AnexoDTO;
import br.com.wssa.email.dto.EmailDTO;
import br.com.wssa.email.dto.HeaderDTO;


/**
 * <b>Nome:</b> EmailUtil <br>
 * <b>Proposito:</b> Classe utilit�ria para aux�liar a cria��o de email
 * (body/mime type).<br>
 * <b>Equipe:</b> HP Enterprise Service <br>
 * <b>Parametro de compilacao: </b>-d.
 * 
 * @author:Hewlett-Packard Company Copyright (c) 2011
 * @version 1.0
 * @return: NA.
 * @throws: NA.
 * @see: NA.
 *       <p>
 *       Registro de Manutencao:
 *       <li>Data :</li>
 *       <li>Autor:</li>
 *       <li>Responsavel:</li>
 *       </p>
 */
public final class EmailUtil {

	/**
	 * Construtor Padrao Instancia um novo objeto EmailUtil.
	 */
	private EmailUtil() {
	}

	/**
	 * Nome: enviarEmail Enviar email.
	 * 
	 * @param email
	 *            the email
	 * @throws Exception
	 *             the exception
	 * @return O conteudo do email original no padrao RFC 822
	 */
	public static void enviarEmail(EmailDTO email) throws Exception {
		Message mensagem = criarMensagem(email, null);
		enviarEmail(mensagem);
	}

	public static void enviarEmail(Message mensagem) throws Exception {
		Transport.send(mensagem);
	}

	public static String obterFonteMensagemOriginal(Message mensagem) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		mensagem.writeTo(baos);
		String emailOriginal = new String(baos.toByteArray());
		baos.close();
		return emailOriginal;
	}

	/**
	 * Nome: criarMensagem Criar mensagem.
	 * 
	 * @param email
	 *            the email
	 * @return message
	 * @throws Exception
	 *             the exception
	 * @see
	 */
	public static Message criarMensagem(final EmailDTO email, String ambiente) throws Exception {

		final MimeMessage mensagem = new MimeMessage(getSession());

		mensagem.setSentDate(new Date());
		mensagem.setSubject(email.getAssunto(), "ISO-8859-1");
		mensagem.setFrom(new InternetAddress(email.getRemetente()));
		mensagem.setRecipients(Message.RecipientType.TO, getEmailTo(email.getDestinatarios()));

		if (CollectionUtils.isNotEmpty(email.getDestinatariosCC())) {
			mensagem.setRecipients(Message.RecipientType.CC, getEmailTo(email.getDestinatariosCC()));
		}
		
		if (CollectionUtils.isNotEmpty(email.getDestinatariosCCO())) {
			mensagem.setRecipients(Message.RecipientType.BCC, getEmailTo(email.getDestinatariosCCO()));
		}

		final MimeMultipart mpRoot = new MimeMultipart("mixed");
		final MimeMultipart mpContent = new MimeMultipart("alternative");
		final MimeBodyPart contentPartRoot = new MimeBodyPart();

		contentPartRoot.setContent(mpContent);
		mpRoot.addBodyPart(contentPartRoot);

		if (email.getHeaders() != null && !email.getHeaders().isEmpty()) {
			for (HeaderDTO headerBean : email.getHeaders()) {
				mensagem.setHeader(headerBean.getNome(), headerBean.getValor());
			}
		}

		if (email.getAnexo() != null) {
			for (AnexoDTO anexo : email.getAnexo()) {
				mpRoot.addBodyPart(adicionarAnexo(anexo));
			}
		}

		if (email.getTemplate() != null) {
			mpContent.addBodyPart(adicionarConteudoHtml(email.getTemplate()));
		}

		mensagem.setContent(mpRoot);
		mensagem.saveChanges();

		return mensagem;
	}

	/**
	 * Nome: getSession Recupera o valor do atributo 'session'.
	 * 
	 * @param funcionalidade
	 *            the funcionalidade
	 * @return valor do atributo 'session'
	 * @throws NamingException
	 *             the naming exception
	 * @see
	 */
	private static Session getSession() throws NamingException {

		final Context context = new InitialContext();

		final Session mailSession = (Session) context.lookup("java:jboss/mail/smmb");

		return mailSession;
	}

	/**
	 * Recupera a lista de e-mails.
	 * 
	 * @param contatos
	 *            the contatos
	 * @return valor do atributo 'emailTo'
	 * @throws Exception
	 *             the exception
	 * @see
	 */
	private static InternetAddress[] getEmailTo(final List<String> contatos) throws Exception {

		InternetAddress[] addressTo = new InternetAddress[contatos.size()];
		for (int i = 0; i < contatos.size(); i++) {
			addressTo[i] = new InternetAddress((String) contatos.get(i));
		}
		return addressTo;
	}

	/**
	 * Nome: adicionarAnexoDTO Adicionar anexo.
	 * 
	 * @param anexo
	 *            the anexo
	 * @return mime body part
	 * @throws MessagingException
	 *             the messaging exception
	 * @see
	 */
	private static MimeBodyPart adicionarAnexo(AnexoDTO anexo) throws MessagingException {
		MimeBodyPart mbp = new MimeBodyPart();
		DataSource fileDataSource = new ByteArrayDataSource(anexo.getArquivo(), anexo.getMimeType());

		mbp.setDisposition(Part.ATTACHMENT);
		mbp.setDataHandler(new DataHandler(fileDataSource));
		mbp.setFileName(anexo.getNome());

		addHeaders(anexo, mbp);

		return mbp;
	}

	private static void addHeaders(AnexoDTO anexo, MimeBodyPart mbp) throws MessagingException {

		List<HeaderDTO> headers = anexo.getHeaders();

		if (headers != null && !headers.isEmpty()) {
			for (HeaderDTO header : headers) {
				mbp.setHeader(header.getNome(), header.getValor());
			}
		}
	}

	/**
	 * Nome: adicionarConteudoHtml Adicionar conteudo html.
	 * 
	 * @param htmlText
	 *            the html text
	 * @return mime body part
	 * @throws MessagingException
	 *             the messaging exception
	 * @see
	 */
	private static MimeBodyPart adicionarConteudoHtml(final String htmlText) throws MessagingException {
		final MimeBodyPart mbp = new MimeBodyPart();
		mbp.setContent(htmlText, "text/html; charset=UTF-8");
		return mbp;
	}
}